﻿using System;
using com.cruxomatic.BusinessFacades;
using com.cruxomatic.configuration.FeatureManager;
using com.cruxomatic.views.Enums;
using com.cruxomatic.DTOs;
using com.cruxomatic.views.Administration;
using com.cruxomatic.logging.Enums;
using com.cruxomatic.logging;
using com.cruxomatic.exceptions;
using com.cruxomatic.security;
using com.cruxomatic.configuration;
using com.cruxomatic.contracts.Plugins;

namespace com.cruxomatic.controllers.Administration
{
    public class ManageUsersController
    {
        readonly IManageUsers _view;
        public ManageUsersController(IManageUsers view)
        {
            _view = view;
        }

        public void InitView(bool IsPostBack)
        {
            if (!IsPostBack)
            {
                 CheckValidity();
                 SwitchToListMode();
            }
        }

        private void CheckValidity()
        {
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            SessionData sessionData = new SessionData();
            UserInformation currentuser = sessionData.CurrentUser;
            if (!cruxSecurityManager.IsUserSuperAdminOrCompanyAdmin(currentuser, _view.CompanyID))
                NavigationController.OpenErrorPage("803");

        }
        public void OpenUser(int UserID)
        {
            CheckValidity(UserID);
            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserInformation userInformation = securityManager.GetUser(UserID);
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            _view.CurrentUser = userInformation;
            _view.FormMode = FormMode.AddEdit;
            if (UserID > 0)
            {
                if (featureManager.IsFeatureSupported("EditUserName"))
                    _view.IsEditUserNameSupported = true;
                else
                    _view.IsEditUserNameSupported = false;
            }
            else
                _view.IsEditUserNameSupported = true;
        }

        public void CreateUser()
        {
            OpenUser(0);
        }

        public void SaveUser()
        {
            try
            {
                UserController.SaveUser(_view.CurrentUser);
                UserInformation user = _view.CurrentUser;
                ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
                UserInformation userInformation = securityManager.GetUser(user.UserName);
                if(_view.CurrentUser.UserID == 0)
                {
                    IProcessor<UserInformation> plugObject = (IProcessor<UserInformation>)CruxConfigurationManager.GetProcessor("UserProcessor");
                    if (plugObject != null)
                    {
                        plugObject.FirePostprocessAction(userInformation);
                    } 
                }
                SwitchToListMode();
            }
            catch (CruxDatabaseException ex)
            {
                ApplicationLogger.LogApplicationMessage(ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError(ex.ErrorNameOrCode);
            }
            catch (CruxNotificationException ex)
            {
                ApplicationLogger.LogApplicationMessage(ex.Message, ApplicationLogType.Notification, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError(ex.ErrorNameOrCode);
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
            }
        }

        public void SwitchToListMode()
        {
            IFeatureManager featureManager = FeatureManagerFactory.GetFeatureManager();
            _view.ErrorDetails = null;
            _view.CurrentUser = new UserInformation();
            _view.IsAddUserSupported = featureManager.IsFeatureSupported("AddUser");
            _view.IsEditUserSupported = featureManager.IsFeatureSupported("EditUser");
            _view.IsEditUserDetailSupported = featureManager.IsFeatureSupported("ShowEditUserDetailAction");
            _view.IsResetUserPasswordSupported = featureManager.IsFeatureSupported("ResetUserPassword");
            _view.IsDeleteUserSupported = featureManager.IsFeatureSupported("DeleteUser");
            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            _view.Users = securityManager.GetUsers(_view.CompanyID);
            _view.FormMode = FormMode.List;
        }

        public void CancelAddEdit()
        {
            SwitchToListMode();
        }

        public void DeleteUser(int UserID)
        {

            try
            {
                CheckValidityForDelete(UserID);
                UserFacade userFacade = new UserFacade();
                ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
                UserInformation userInformation = securityManager.GetUser(UserID);
                IProcessor<UserInformation> plugObject = (IProcessor<UserInformation>)CruxConfigurationManager.GetProcessor("UserProcessor");
                if (plugObject != null)
                {
                    plugObject.FirePreprocessAction(userInformation);
                } 
                userFacade.DeleteUser(UserID);
                SwitchToListMode();
            }
            catch (Exception ex)
            {
                ApplicationLogger.LogApplicationMessage(
                    ex.Message, ApplicationLogType.Database, ex.StackTrace);
                _view.ErrorDetails = CruxApplicationErrorManager.GetApplicationError("101", ex.Message);
            }
        }


        private void CheckValidity(int UserID)
        {
            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserInformation userBeingModified = securityManager.GetUser(UserID);
            SessionData sessionData = new SessionData();
            UserInformation currentUser = (UserInformation)sessionData.CurrentUser;
            ICruxSecurityManager cruxSecurityManager = CruxSecurityManagerFactory.GetSecurityManager();
            if (!cruxSecurityManager.IsUserAuthorizedToEditUser(currentUser, userBeingModified))
                NavigationController.OpenErrorPage("801");

        }

        private void CheckValidityForDelete(int UserID)
        {
            CheckValidity(UserID);

            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            UserInformation userBeingModified = securityManager.GetUser(UserID);
            SessionData sessionData = new SessionData();
            UserInformation currentUser = sessionData.CurrentUser;

            if (currentUser.UserID == userBeingModified.UserID)
                NavigationController.OpenErrorPage("806");

        }
        public void ManageUserDetails(int userid)
        {
            NavigationController.OpenView("ManageUserDetails", userid);
        }

        public void ResetUserPassword(int userid)
        {
            NavigationController.OpenView("ResetPassword", userid);
        }

        public CompanyInformation GetCompanyName(int CompanyID)
        {
            ICruxSecurityManager securityManager = CruxSecurityManagerFactory.GetSecurityManager();
            return securityManager.GetCompany(CompanyID);
        }

        public void RedirectToPreviousPage()
        {
            NavigationController.OpenView("ManageCompany", _view.CompanyID);
        }
    }
}
